package cz.fi.muni.pb138.spring2013.dtd2xsd.entities;

import cz.fi.muni.pb138.spring2013.dtd2xsd.visitor.interfaces.ContentRestriction;
import cz.fi.muni.pb138.spring2013.dtd2xsd.visitor.interfaces.ExtendedContentRestriction;
import cz.fi.muni.pb138.spring2013.dtd2xsd.visitor.interfaces.Visitor;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Objects;

/**
 * This class represents a sequence of children elements separated by commas
 * inside a DTD "ELEMENT ..." tag. It is equivalent to "xs:sequence" in XML
 * Schema.
 *
 * @author Slavomir Krupa
 */
public class SequenceRestriction implements ExtendedContentRestriction {

    private List<ContentRestriction> elements = new ArrayList();
    private boolean required;
    private boolean multiple;

    public SequenceRestriction() {
        this.required = true;
        this.multiple = false;
    }

    @Override
    public void accept(Visitor visitor) {
        visitor.visit(this);
        for (ContentRestriction contentRestriction : elements) {
            contentRestriction.accept(visitor);
        }
    }

    @Override
    public boolean isRequired() {
        return required;
    }

    @Override
    public void setRequired(boolean required) {
        this.required = required;
    }

    @Override
    public boolean isMultiple() {
        return multiple;
    }

    @Override
    public void setMultiple(boolean multiple) {
        this.multiple = multiple;
    }

    public void addElement(ContentRestriction element) {
        this.elements.add(element);
    }

    public List<ContentRestriction> getElements() {
        return Collections.unmodifiableList(elements);
    }

    @Override
    public int hashCode() {
        int hash = 7;
        hash = 97 * hash + Objects.hashCode(this.elements);
        hash = 97 * hash + (this.required ? 1 : 0);
        hash = 97 * hash + (this.multiple ? 1 : 0);
        return hash;
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == null) {
            return false;
        }
        if (getClass() != obj.getClass()) {
            return false;
        }
        final SequenceRestriction other = (SequenceRestriction) obj;
        if (!Objects.equals(this.elements, other.elements)) {
            return false;
        }
        if (this.required != other.required) {
            return false;
        }
        if (this.multiple != other.multiple) {
            return false;
        }
        return true;
    }
    
}
